#include<set>
#include "nfa.h"
const int maxn = 100;
class State {
public:
    State() { length = 0; }
    int getLength()
    {
        return this->length;
    }
    int getSet(int n)
    {
        return setJ[n];
    }
    void set(int n)
    {
        setJ[length] = n;
        length++;
    }
    string getAll()
    {
        string s;
        for (int i = 0; i < length; i++)
            s = s.append(to_string(setJ[i]) + " ");
        return s;
    }
    bool find(int element)
    {
        for (int i = 0; i < length; i++)
            if (setJ[i] == element)
                return true;
        return false;
    }
private:
    int setJ[maxn];
    int length;
};

struct Relation {
    bool isEqual(State* pre, State* next)
    {
        if (preState->getLength() != pre->getLength() || nextState->getLength() != next->getLength())
            return false;
        else
        {
            for (int i = 0; i < pre->getLength(); i++)
                if (!pre->find(preState->getSet(i)))
                    return false;
            for (int i = 0; i < next->getLength(); i++)
                if (!next->find(nextState->getSet(i)))
                    return false;

        }
        return true;
    }
    State* preState;
    char inputChar;
    State* nextState;
};

void getEClosure(Edge* e, int cntEdge, State* st)
{
    for (int i = 0; i < st->getLength(); i++)
    {
        for (int j = 0; j < cntEdge; j++)
        {
            if (st->getSet(i) == stoi(e[j].getBegin()) && e[j].getletter() == '#')
            {
                bool flag = 0;
                for (int k = 0; k < st->getLength(); k++)
                    if (st->getSet(k) == stoi(e[j].getEnd()))
                        flag = 1;
                if (flag == 0)
                    st->set(stoi(e[j].getEnd()));
            }
        }
    }
}

void moveT(char t, Edge* e, int cntEdge, State* source, State* dest)
{

    for (int i = 0; i < source->getLength(); i++)
        for (int j = 0; j < cntEdge; j++)
            if (source->getSet(i) == stoi(e[j].getBegin()) && e[j].getletter() == t)
                dest->set(stoi(e[j].getEnd()));
}
int isInsert(vector<State*> allSet, State* newSet)
{
    int num = 0;
    for (auto set : allSet)
    {
        bool found = true;
        if (set->getLength() == newSet->getLength())
        {
            for (int i = 0; i < newSet->getLength(); i++)
            {
                if (!set->find(newSet->getSet(i)))
                {
                    found = false;
                    break;
                }
            }
            if (found)
                return num;
        }
        num++;
    }
    return num;
}

bool isInsertForRel(vector<Relation*> rel, State* preState, char t, State* nextState)
{
    for (int i = 0; i < rel.size(); i++)
        if (rel.at(i)->isEqual(preState, nextState) && (rel.at(i)->inputChar == t))
            return false;
    return true;
}

